/*
 * This file is part of b.AMP.
 *
 * b.AMP is free software: you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * b.AMP is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with b.AMP.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "logger.hpp"

#include <boost/filesystem.hpp>
#include <boost/thread.hpp>

#include <fstream>
#include <iostream>
#include <string>

struct bamp::Logger::Implementation
{
    Implementation()
        : mutex(),
          stderrEnable(true),
          outputFile()
    {}

    boost::mutex  mutex;
    bool          stderrEnable;
    std::ofstream outputFile;
};

void bamp::Logger::setStderr(const bool enable)
{
    boost::mutex::scoped_lock lock(impl().mutex);
    impl().stderrEnable = enable;
}


void bamp::Logger::setFile(const boost::filesystem::path& filename)
{
    boost::mutex::scoped_lock lock(impl().mutex);

    std::ofstream& file = impl().outputFile;
    file.exceptions ( std::ofstream::failbit | std::ofstream::badbit );
    if (file.is_open())
    {
        file.close();
    }
    if (!filename.empty())
    {
        file.open(filename.string().c_str());
    }
}


void bamp::Logger::__log(const std::string& prefix, const std::string& msg)
{
    boost::mutex::scoped_lock lock(impl().mutex);

    std::string outputString = prefix + ": " + msg;

    if (impl().stderrEnable)
    {
        std::cerr << outputString << std::endl;
    }
    if (impl().outputFile.is_open())
    {
        impl().outputFile << outputString << std::endl;
    }
}

bamp::Logger::Implementation& bamp::Logger::impl()
{
    static Implementation __impl;
    return __impl;
}
